package com.example.demo.producer;

import com.example.rabbitmq.starter.exception.ApiResponse;
import com.example.rabbitmq.starter.exception.BusinessException;
import com.example.rabbitmq.starter.producer.MessageProducerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;

/**
 * 高级消息生产者示例
 * 演示如何在不同交换机类型下使用动态路由键
 */
@RestController
@RequestMapping("/api/example/advanced")
public class AdvancedMessageProducer {

    private static final Logger log = LoggerFactory.getLogger(AdvancedMessageProducer.class);

    @Autowired
    private MessageProducerFactory producerFactory;

    /**
     * 发送Direct交换机消息（使用配置的默认路由键）
     * 适用于点对点消息传递
     */
    @PostMapping("/direct/default")
    public ApiResponse<String> sendDirectMessage(
            @RequestParam String businessId,
            @RequestBody @Valid Map<String, Object> content) {

        // 获取Direct交换机的生产者（假设配置名为DIRECT_MESSAGE）
        MessageProducerFactory.BusinessMessageProducer producer = producerFactory.getProducer("WChat");

        // 使用默认路由键发送消息
        boolean success = producer.sendMessage(businessId, content);

        if (success) {
            return ApiResponse.success("Direct消息发送成功");
        }
        else {
            throw new BusinessException("Direct消息发送失败，请稍后重试");
        }
    }

    /**
     * 发送Topic交换机消息（指定动态路由键）
     * 适用于基于主题的消息路由
     */
    @PostMapping("/topic/dynamic")
    public ApiResponse<Map<String, Object>> sendTopicMessage(
            @RequestParam String businessId,
            @RequestParam String routingKey,
            @RequestBody @Valid Map<String, Object> content) {

        // 获取Topic交换机的生产者（假设配置名为TOPIC_MESSAGE）
        MessageProducerFactory.BusinessMessageProducer producer = producerFactory.getProducer("TOPIC_MESSAGE");

        // 使用动态路由键发送消息
        // 例如: user.create, user.update, order.create, order.cancel
        boolean success = producer.sendMessage(businessId, content, routingKey);

        if (success) {
            Map<String, Object> result = new HashMap<>();
            result.put("routingKey", routingKey);
            return ApiResponse.success("Topic消息发送成功", result);
        }
        else {
            throw new BusinessException("Topic消息发送失败，请稍后重试");
        }
    }

    /**
     * 发送Fanout交换机消息
     * 广播消息，路由键会被忽略
     */
    @PostMapping("/fanout/broadcast")
    public ApiResponse<String> sendFanoutMessage(
            @RequestParam String businessId,
            @RequestBody @Valid Map<String, Object> content) {

        // 获取Fanout交换机的生产者（假设配置名为FANOUT_MESSAGE）
        MessageProducerFactory.BusinessMessageProducer producer = producerFactory.getProducer("FANOUT_MESSAGE");

        // Fanout交换机会忽略路由键，广播到所有绑定的队列
        // 但我们仍然可以传递一个路由键（通常为空字符串或任意值）
        boolean success = producer.sendMessage(businessId, content, "");

        if (success) {
            return ApiResponse.success("Fanout广播消息发送成功");
        }
        else {
            throw new BusinessException("Fanout广播消息发送失败，请稍后重试");
        }
    }

    /**
     * 发送带优先级的消息（指定路由键）
     */
    @PostMapping("/priority")
    public ApiResponse<Map<String, Object>> sendPriorityMessage(
            @RequestParam String businessId,
            @RequestParam String routingKey,
            @RequestParam(defaultValue = "0") int priority,
            @RequestBody @Valid Map<String, Object> content) {

        MessageProducerFactory.BusinessMessageProducer producer = producerFactory.getProducer("PRIORITY_MESSAGE");

        // 发送带优先级和指定路由键的消息
        boolean success = producer.sendMessageWithPriorityAndRoutingKey(businessId, content, priority, routingKey);

        if (success) {
            Map<String, Object> result = new HashMap<>();
            result.put("priority", priority);
            result.put("routingKey", routingKey);
            return ApiResponse.success("优先级消息发送成功", result);
        }
        else {
            throw new BusinessException("优先级消息发送失败，请稍后重试");
        }
    }

    /**
     * 发送延迟消息（指定路由键）
     */
    @PostMapping("/delay")
    public ApiResponse<Map<String, Object>> sendDelayMessage(
            @RequestParam String businessId,
            @RequestParam String routingKey,
            @RequestParam long delayMs,
            @RequestBody @Valid Map<String, Object> content) {

        MessageProducerFactory.BusinessMessageProducer producer = producerFactory.getProducer("DELAY_MESSAGE");

        // 发送延迟消息并指定路由键
        boolean success = producer.sendDelayMessage(businessId, content, delayMs, routingKey);

        if (success) {
            Map<String, Object> result = new HashMap<>();
            result.put("delayMs", delayMs);
            result.put("routingKey", routingKey);
            return ApiResponse.success("延迟消息发送成功", result);
        }
        else {
            throw new BusinessException("延迟消息发送失败，请稍后重试");
        }
    }

    /**
     * 批量发送Topic消息到不同路由键
     */
    @PostMapping("/topic/batch")
    public ApiResponse<Map<String, Object>> sendBatchTopicMessages(
            @RequestParam String businessId,
            @RequestBody @Valid Map<String, Object> content) {

        MessageProducerFactory.BusinessMessageProducer producer = producerFactory.getProducer("TOPIC_MESSAGE");

        // 模拟发送到不同的路由键
        String[] routingKeys = {
                "user.create",
                "user.update",
                "user.delete",
                "order.create",
                "order.payment",
                "order.shipped"
        };

        int successCount = 0;
        for (String routingKey : routingKeys) {
            Map<String, Object> messageContent = new HashMap<>(content);
            messageContent.put("routingKey", routingKey);
            messageContent.put("timestamp", System.currentTimeMillis());

            boolean success = producer.sendMessage(businessId + "_" + routingKey, messageContent, routingKey);
            if (success) {
                successCount++;
            }
        }

        if (successCount > 0) {
            Map<String, Object> result = new HashMap<>();
            result.put("successCount", successCount);
            result.put("totalCount", routingKeys.length);
            return ApiResponse.success(String.format("批量发送完成，成功: %d/%d", successCount, routingKeys.length), result);
        }
        else {
            throw new BusinessException("批量消息发送全部失败，请稍后重试");
        }
    }
}